<template>
    <el-form label-width="100px">
        <el-form-item label="SPU名称">
            <el-input placeholder="请你输入SPU名称" v-model="SpuParams.spuName"></el-input>
        </el-form-item>
        <el-form-item label="SPU品牌" v-model="SpuParams.tmId">
            <el-select style="width: 200px;">
                <el-option v-for="(item, index) in AllTradeMark" :key="item.id" :label="item.tmName"
                    :value="item.id"></el-option>
            </el-select>
        </el-form-item>
        <el-form-item label="SPU描述">
            <el-input type="textarea" placeholder="请你输入SPU描述" v-model="SpuParams.description"
                class="inner-height-textarea"></el-input>
        </el-form-item>
        <el-form-item label="SPU照片">
            <!-- upload
                v-model:file-list:展示默认 图片
                action:上传图片的接口
                list-type:文件展示的模式类型
                on-preview：照片墙点击预览按钮的时候触发的钩子
                on-remove: 移除文件|照片的钩子
            -->
            <el-upload v-model:file-list="imgList" action="/api/admin/product/fileUpload" list-type="picture-card"
                :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :before-upload="handlerUpload">
                <el-icon>
                    <Plus />
                </el-icon>
            </el-upload>

            <el-dialog v-model="dialogVisible">
                <img w-full :src="dialogImageUrl" alt="Preview Image" style="width: 100%; height: 100%;" />
            </el-dialog>
        </el-form-item>
        <el-form-item label="SPU销售属性">
            <el-select v-model="saleAttrIdAndValueName" style="width: 200px;"
                :placeholder="unSelectSaleAttr.length ? `还有${unSelectSaleAttr.length}个未选择` : '无属性可选'">
                <el-option v-for="(item, index) in unSelectSaleAttr" :key="item.id"
                    :value="`${item.id}:${item.name}`"></el-option>
            </el-select>
            <el-button @click="addSaleAttr" :disabled="saleAttrIdAndValueName ? false : true" type="primary" icon="Plus"
                style="margin: 0 5px;">添加属性</el-button>
            <!-- table展示属性与属性值 -->
            <el-table border style="margin: 10px 0px;" :data="saleAttr">
                <el-table-column label="序号" type="index" align="center" width="80px"></el-table-column>
                <el-table-column label="销售属性名字" width="120px" prop="salAttrName"></el-table-column>
                <el-table-column label="销售属性值">
                    <!-- row为每一个属性对象 -->
                    <template #="{ row, $index }">
                        <div class="flex gap-2">
                            <el-tag @close="row.spuSaleAttrValueList.splice(index, 1)" style="margin: 0 5px;"
                                v-for="(item, index) in row.spuSaleAttrValueList" :key="row.id" closable>
                                {{ item.saleAttrValueName }}
                            </el-tag>
                            <el-input @blur="toLook(row)" v-model="row.saleAttrValue" v-if="row.flag"
                                placeholder="请你输入属性值" size="small" style="width: 100px;"></el-input>
                            <el-button v-else @click="toEdit(row)" type="primary" size="small" icon="Plus"></el-button>
                        </div>
                    </template>
                </el-table-column>
                <el-table-column label="操作" width="120px">
                    <template #="{ row, $index }">
                        <el-button type="danger" size="small" icon="Delete"
                            @click="saleAttr.splice($index, 1)"></el-button>

                    </template>
                </el-table-column>
            </el-table>
            <el-form-item>
                <el-button type="primary" @click="save" :disabled="saleAttr.length > 0 ? false : true">保证</el-button>
                <el-button type="primary" @click="cancel">取消</el-button>
            </el-form-item>
        </el-form-item>
    </el-form>
</template>
<script setup lang='ts' name='spuForm'>
import type { TradeMark, SpuData, AllTradeMark, SpuHasImg, SaleAttrResponseData, HasSaleAttrResponseData, SpuImg, SaleAttr, HasSaleAttr, SaleAttrValue } from '@/api/product/spu/type';
import { reqAllTradeMark, reqSpuImageList, reqSpuHasSaleAttr, reqAllSaleAttr, reqAddOrUpdate } from '@/api/product/spu/index'
import { ref, computed } from 'vue';
import { ElMessage } from 'element-plus';
let $emit = defineEmits(['changeScene'])
//点击取消按钮：通知父组件场景切换为0
const cancel = () => {
    $emit('changeScene', {flag:0,params:'update'})
    console.log($emit)
}
//存储spu数据
//所有品牌
let AllTradeMark = ref<TradeMark[]>([])
let imgList = ref<SpuImg[]>([])
// 已有的销售属性
let saleAttr = ref<SaleAttr[]>([])
//全部的销售属性
let allSaleAttr = ref<HasSaleAttr[]>([])
//存储SPU对象
let SpuParams = ref<SpuData>({
    category3Id: '',
    spuName: '',
    description: '',
    tmId: 0,//品牌id
    spuImageList: [],
    spuSaleAttrList: [],
})
//控制照片墙预览按钮气泡框的出现与消失
let dialogVisible = ref<boolean>(false)
//存储气泡框图片地址
let dialogImageUrl = ref<string>('')
//将来收集还未选择的销售属性的ID与属性名
let saleAttrIdAndValueName = ref<string>('')

const initHasSpuData = async (spu: SpuData) => {
    try {
        //spu即为父组件传递过来的已有spu对象
        SpuParams.value = spu
        //品牌
        let result: AllTradeMark = await reqAllTradeMark()
        //spu图片列表
        let result1: SpuHasImg = await reqSpuImageList(spu.id as number)
        //spu属性
        let result2: SaleAttrResponseData = await reqSpuHasSaleAttr(spu.id as number)
        //总销售属性
        let result3: HasSaleAttrResponseData = await reqAllSaleAttr()

        //存储品牌数据
        AllTradeMark.value = result.data
        imgList.value = result1.data.map(item => {
            return {
                name: item.imgName,
                url: item.imgUrl
            }
        })
        saleAttr.value = result2.data
        allSaleAttr.value = result3.data
    } catch (error) {
        ElMessage({
            type: 'error',
            message: '读取数据失败'
        })
    }

}

// 照片墙点击预览按钮的时候触发的钩子
const handlePictureCardPreview = (file: any) => {
    //    v-model已经实现收集与删除逻辑了  不需要额外写
    dialogImageUrl.value = file.url
    dialogVisible.value = true


}
//移除照片墙按钮
const handleRemove = () => {
    //    v-model已经实现收集与删除逻辑了  不需要额外写


}
//照片上传成功之前的钩子
const handlerUpload = (file: any) => {
    if (file.type == 'image/png' || file.type == 'image/jpeg' || file.type == 'image/gif') {
        //文件格式符合
        if (file.size / 1024 / 1024 < 4) {
            //文件大小符合
            return true
        } else {
            //文件大小不符合
            ElMessage({
                type: 'error',
                message: '文件过大,得小于4M'
            })
            return false
        }
    } else {
        //文件格式不符合
        ElMessage({
            type: 'error',
            message: "上传文件格式得为png|jpeg|gif"
        })
        return false
    }
}

//计算出当前SPU未用有的销售属性
let unSelectSaleAttr = computed(() => {
    // 全部的销售属性: 颜色、版本、尺码
    // filter 结果未true才留下
    // every  数组中所有结果都为ture才true  否则false
    let unSelectAttr = allSaleAttr.value.filter(item => {
        return saleAttr.value.every(item1 => {
            return item.name != item1.saleAttrName
        })
    })
    return unSelectAttr
})

//添加销售属性
const addSaleAttr = () => {
    let [baseSaleAttrId, saleAttrName] = saleAttrIdAndValueName.value.split(':')
    //准备一个新的销售属性
    let newSaleAttr: SaleAttr = {
        baseSaleAttrId,
        saleAttrName,
        spuSaleAttrValueList: []
    }
    //追加到数组中
    saleAttr.value.push(newSaleAttr)
    //清空收集的数据
    saleAttrIdAndValueName.value = '';
}
//属性值点击按钮
const toEdit = (row: SaleAttr) => {
    //点击后=>编辑模式
    row.flag = true
    row.saleAttrValue = ''
}
//elinput失去焦点回调
const toLook = (row: SaleAttr) => {
    //整理收集的属性的ID与属性值的名字
    const { baseSaleAttrId, saleAttrValue } = row
    //整理成服务器需要的属性值形式
    let newSaleAttrValue: SaleAttrValue = {
        baseSaleAttrId,
        saleAttrValueName: (saleAttrValue as string),
    }
    //非法清空判断 trim()移除所有空白字符
    if (saleAttrValue?.trim() == '') {
        ElMessage({
            type: 'error',
            message: '不能为空'
        })
        return
    }
    //find会返回找到的那个对象。不是boolean
    let repeat = row.spuSaleAttrValueList.find(item => {
        return item.saleAttrValueName == saleAttrValue
    })
    if (repeat) {
        ElMessage({
            type: 'error',
            message: '不能重复'
        })
        return
    }
    //追加新的属性值对象
    row.spuSaleAttrValueList.push(newSaleAttrValue)
    //切换为查看模式
    row.flag = false
}
const save = async () => {
    //整理参数
    // 1.照片墙
    SpuParams.value.spuImageList = imgList.value.map((item: any) => {
        return {
            imgName: item.name,
            /* 
            下面那个等价于
            if (item.response) {      // 如果是新上传的文件
                imgUrl = item.response.data; 
            } else {                  // 如果是已存在的文件
                imgUrl = item.url;
            }
            */
            imgUrl: (item.response && item.response.data) || item.url
        }
    })
    // 2.销售属性
    SpuParams.value.spuSaleAttrList = saleAttr.value
    //发请求
    let result = await reqAddOrUpdate(SpuParams.value)
    if (result.code == 200) {
        ElMessage({
            type: 'success',
            message: SpuParams.value.id ? '更新成功' : '添加成功'
        })
        //切换场景为0
        $emit('changeScene', {flag:0,params:SpuParams.value.id?'update':'add'})
    } else {
        ElMessage({
            type: 'error',
            message: SpuParams.value.id ? '更新失败' : '添加失败'
        })
    }
}
//添加一个新的SPU初始化请求方法
const initAddSpu = async (c3Id: number | string) => {
    //清空数据
    Object.assign(SpuParams.value, {
        category3Id: '',
        spuName: '',
        description: '',
        tmId: 0,//品牌id
        spuImageList: [],
        spuSaleAttrList: [],
    })
    //清空照片墙和销售属性  这两个一开始不是存SpuParams里的
    imgList.value = []
    saleAttr.value = []
    //还有总品牌下拉菜单中的placeholder也清空
    saleAttrIdAndValueName.value = ''
    //品牌
    SpuParams.value.category3Id = c3Id
    let result: AllTradeMark = await reqAllTradeMark()
    //总销售属性
    let result1: HasSaleAttrResponseData = await reqAllSaleAttr()
    //存储数据
    AllTradeMark.value = result.data;
    allSaleAttr.value = result1.data;

}
//对外暴露
defineExpose({ initHasSpuData, initAddSpu })
</script>


<style scoped>
/* 使用深度选择器 */
.inner-height-textarea :deep(.el-textarea__inner) {
    height: 150px;
    min-height: 150px !important;
    resize: none;
}
</style>